<?php

namespace App\Command;

use App\Model\Admin\MenuModel;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\ORM\DbManager;

/**
 * 代码生成器-服务类
 */
class GenerateService
{
    /**
     * 一键生成
     */
    public function generate($tables)
    {
        foreach ($tables as $table) {
            // 数据表名称
            $tableName = str_replace(DB_PREFIX, null, $table['tableName']);
            $tableNameArr = explode('_', $tableName);
            $moduleName = '';
            $controllerName = '';
            if (!is_array($tableNameArr)) {
                $moduleName = $tableName;
                $controllerName = $tableName;
            } else {
                foreach ($tableNameArr as $item) {
                    $moduleName .= ucwords(trim($item));
                }
                $controllerName = $moduleName;
            }

//            // 模型名称
//            $moduleName = str_replace(' ', null, ucwords(strtolower(str_replace('_', ' ', $tableName))));
//            // 控制器名称
//            $controllerName = ucfirst(strtolower(str_replace('_', '', $tableName)));

            // 数据表描述
            $comment = $table['tableComment'] ?? '未定义表';
            if (!$comment) {
                return "数据表名称不能为空";
            }
            // 去除表描述中的`表`
            if (strpos($comment, "表") !== false) {
                $comment = str_replace("表", null, $comment);
                $menuName = $comment;
            }
            // 去除表描述中的`管理`
            if (strpos($comment, "管理") !== false) {
                $comment = str_replace("管理", null, $comment);
            }
            // 作者花名
            $author = "LZH";

            // 生成模型
//            $this->generateModel($author, $moduleName, $comment, $tableName);
//            // 生成服务类
//            $this->generateService($author, $moduleName, $comment, $tableName);
//            // 生成控制器
//            $this->generateController($author, $controllerName, $comment, $tableName);
//            // 生成列表文件
            $this->generateVueIndex($comment, $moduleName, $tableName);
//            // 生成菜单
//            $this->generateMenu(strtolower(str_replace('_', '', $tableName)), $menuName);
        }
    }

    /**
     * 生成模型
     * @param string $author 作者
     * @param string $moduleName 模块名
     * @param string $moduleTitle 模块标题
     * @param string $tableName 数据表名
     */
    public function generateModel(string $author, string $moduleName, string $moduleTitle, string $tableName)
    {
        // 判断是否有图片
        $moduleImage = false;
        // 获取数据列表
        $columnList = $this->getColumnList(DB_PREFIX . "{$tableName}");
        if ($columnList) {
            foreach ($columnList as &$val) {
                // 图片字段处理
                if (strpos($val['columnName'], "cover") !== false ||
                    strpos($val['columnName'], "avatar") !== false ||
                    strpos($val['columnName'], "image") !== false ||
                    strpos($val['columnName'], "logo") !== false ||
                    strpos($val['columnName'], "pic") !== false) {
                    $val['columnImage'] = true;
                    $moduleImage = true;
                }
            }
        }
        // 参数
        $param = [
            'author' => $author,
            'since' => date('Y/m/d', time()),
            'moduleName' => $moduleName,
            'moduleTitle' => $moduleTitle,
            'tableName' => $tableName,
            'columnList' => $columnList,
            'moduleImage' => $moduleImage,
        ];
        // 存储目录
        $FILE_PATH = EASYSWOOLE_ROOT . '/App/Model/Admin/';
        if (!is_dir($FILE_PATH)) {
            // 创建目录并赋予权限
            mkdir($FILE_PATH, 0777, true);
        }
        // 文件名
        $filename = $FILE_PATH . "/{$moduleName}Model.php";
        // 拆解参数
        extract($param);
        // 开启缓冲区
        ob_start();
        // 引入模板文件
        require(EASYSWOOLE_ROOT . '/templates/model.tpl.php');
        // 获取缓冲区内容
        $out = ob_get_clean();
        // 打开文件
        $f = fopen($filename, 'w');
        // 写入内容
        fwrite($f, "<?php " . $out);
        // 关闭
        fclose($f);
    }

    /**
     * 生成服务类
     * @param string $author 作者
     * @param string $moduleName 模块名
     * @param string $moduleTitle 模块标题
     * @param string $tableName 数据表
     */
    public function generateService(string $author, string $moduleName, string $moduleTitle, string $tableName)
    {
        // 判断是否有图片
        $moduleImage = false;
        // 查询条件
        $queryList = [];
        // 获取数据列表
        $columnList = $this->getColumnList(DB_PREFIX . "{$tableName}");
        if ($columnList) {
            foreach ($columnList as &$val) {
                // 图片字段处理
                if (strpos($val['columnName'], "cover") !== false ||
                    strpos($val['columnName'], "avatar") !== false ||
                    strpos($val['columnName'], "image") !== false ||
                    strpos($val['columnName'], "logo") !== false ||
                    strpos($val['columnName'], "pic") !== false) {
                    $val['columnImage'] = true;
                    $moduleImage = true;
                }
                // 下拉筛选
                if (isset($val['columnValue'])) {
                    $queryList[] = $val;
                }
                // 名称
                if ($val['columnName'] == "name") {
                    $queryList[] = $val;
                }
                // 标题
                if ($val['columnName'] == "title") {
                    $queryList[] = $val;
                }
            }
        }

        // 参数
        $param = [
            'author' => $author,
            'since' => date('Y/m/d', time()),
            'moduleName' => $moduleName,
            'moduleTitle' => $moduleTitle,
            'columnList' => $columnList,
            'moduleImage' => $moduleImage,
            'queryList' => $queryList,
        ];
        // 存储目录
        $FILE_PATH = EASYSWOOLE_ROOT . '/App/Service/Admin/';
        if (!is_dir($FILE_PATH)) {
            // 创建目录并赋予权限
            mkdir($FILE_PATH, 0777, true);
        }
        // 文件名
        $filename = $FILE_PATH . "/{$moduleName}Service.php";
        // 拆解参数
        extract($param);
        // 开启缓冲区
        ob_start();
        // 引入模板文件
        require(EASYSWOOLE_ROOT . '/templates/service.tpl.php');
        // 获取缓冲区内容
        $out = ob_get_clean();
        // 打开文件
        $f = fopen($filename, 'w');
        // 写入内容
        fwrite($f, "<?php " . $out);
        // 关闭
        fclose($f);
    }

    /**
     * 生成控制器
     * @param string $author 作者
     * @param string $moduleName 模块名
     * @param string $moduleTitle 模块标题
     * @param string $tableName 数据表名
     */
    public function generateController(string $author, string $moduleName, string $moduleTitle, string $tableName)
    {
        // 获取数据列表
        $columnList = $this->getColumnList(DB_PREFIX . "{$tableName}");
        // 参数
        $param = [
            'author' => $author,
            'since' => date('Y/m/d', time()),
            'moduleName' => $moduleName,
            'moduleTitle' => $moduleTitle,
            'columnList' => $columnList,
        ];
        // 存储目录
        $FILE_PATH = EASYSWOOLE_ROOT . '/App/HttpController/Api/Admin/';
        if (!is_dir($FILE_PATH)) {
            // 创建目录并赋予权限
            mkdir($FILE_PATH, 0777, true);
        }
        // 文件名
        $filename = $FILE_PATH . "/{$param['moduleName']}.php";
        // 拆解参数
        extract($param);
        // 开启缓冲区
        ob_start();
        // 引入模板文件
        require(EASYSWOOLE_ROOT . '/templates/controller.tpl.php');
        // 获取缓冲区内容
        $out = ob_get_clean();
        // 打开文件
        $f = fopen($filename, 'w');
        // 写入内容
        fwrite($f, "<?php " . $out);
        // 关闭
        fclose($f);
    }

    /**
     * 生成列表文件
     * @param string $moduleTitle 模块标题
     * @param string $moduleName 模块名称
     * @param string $tableName 数据表名
     */
    public function generateVueIndex(string $moduleTitle, string $moduleName, string $tableName)
    {
        // 获取数据列表
        $columnList = $this->getColumnList(DB_PREFIX . "{$tableName}");
        $queryList = [];
        if ($columnList) {
            foreach ($columnList as $val) {
                // 下拉筛选
                if (isset($val['columnValue'])) {
                    $queryList[] = $val;
                }
                // 名称
                if ($val['columnName'] == "name") {
                    $queryList[] = $val;
                }
                // 标题
                if ($val['columnName'] == "title") {
                    $queryList[] = $val;
                }
            }
        }
        // 获取编辑表单数据源
        // 剔除非表单呈现字段
        $arrayList = [];
        $tempList = [];
        $rowList = [];
        $columnSplit = false;
        if ($columnList) {
            foreach ($columnList as $val) {
                // 记录ID
                if ($val['columnName'] == "id") {
                    continue;
                }
                // 创建人
                if ($val['columnName'] == "create_id") {
                    continue;
                }
                // 创建时间
                if ($val['columnName'] == "create_time") {
                    continue;
                }
                // 更新人
                if ($val['columnName'] == "update_id") {
                    continue;
                }
                // 更新时间
                if ($val['columnName'] == "update_time") {
                    continue;
                }
                // 有效标识
                if ($val['columnName'] == "mark") {
                    continue;
                }
                // 图片字段处理
                if (strpos($val['columnName'], "cover") !== false ||
                    strpos($val['columnName'], "avatar") !== false ||
                    strpos($val['columnName'], "image") !== false ||
                    strpos($val['columnName'], "logo") !== false ||
                    strpos($val['columnName'], "pic") !== false) {
                    $val['columnUpload'] = true;
                    $tempList[] = $val;
                    continue;
                }
                // 多行文本输入框
                if (strpos($val['columnName'], "note") !== false ||
                    strpos($val['columnName'], "content") !== false ||
                    strpos($val['columnName'], "description") !== false ||
                    strpos($val['columnName'], "intro") !== false) {
                    $val['columnRow'] = true;
                    $rowList[] = $val;
                    continue;
                }
                // 由于目前时间字段采用int类型，所以这里根据字段描述模糊确定是否是时间选择
                if (strpos($val['columnComment'], "时间") !== false) {
                    $val['dataType'] = 'datetime';
                } elseif (strpos($val['columnComment'], "日期") !== false) {
                    $val['dataType'] = 'date';
                }

                // 图片字段处理
                if (strpos($val['columnName'], "cover") !== false ||
                    strpos($val['columnName'], "avatar") !== false ||
                    strpos($val['columnName'], "image") !== false ||
                    strpos($val['columnName'], "logo") !== false ||
                    strpos($val['columnName'], "pic") !== false) {
                    $val['columnImage'] = true;
                }
                $arrayList[] = $val;
            }
        }
        if (count($arrayList) + count($tempList) + count($rowList) > 105) {
            $dataList = [];
            // 分两个一组
            $dataList = array_chunk($arrayList, 2);
            // 图片
            if (count($tempList) > 0) {
                array_unshift($dataList, $tempList);
            }
            // 多行文本
            if (count($rowList) > 0) {
                foreach ($rowList as $val) {
                    $dataList[][] = $val;
                }
            }
            $columnList = $dataList;
            $columnSplit = true;
        } else {
            $dataList = $arrayList;
//            // 图片
//            if (count($tempList) > 0) {
//                array_unshift($dataList, $tempList);
//            }
            // 多行文本
            if (count($rowList) > 0) {
                foreach ($rowList as $val) {
                    $dataList[][] = $val;
                }
            }
            $columnList = $dataList;
            $columnSplit = false;
        }

        $columnList = array_unique($columnList, SORT_REGULAR);
//        print_r($columnList);

        // 参数
        $param = [
            'moduleName' => $moduleName,
            'moduleName2' => strtolower($moduleName),
            'moduleTitle' => $moduleTitle,
            'queryList' => $queryList,
            'columnList' => $columnList,
        ];
        // 存储目录
        if (strpos($tableName, "_") !== false) {
            $tableName = str_replace('_', null, $tableName);
        }
        $FILE_PATH = EASYSWOOLE_ROOT . '/../smart_campus_web/src/views/system/' . strtolower($tableName);
        if (!is_dir($FILE_PATH)) {
            // 创建目录并赋予权限
            mkdir($FILE_PATH, 0777, true);
        }
        // 文件名
        $filename = $FILE_PATH . "/index.vue";
        // 拆解参数
        extract($param);
        // 开启缓冲区
        ob_start();
        // 引入模板文件
        require(EASYSWOOLE_ROOT . '/templates/index.vue.php');
        // 获取缓冲区内容
        $out = ob_get_clean();
        // 打开文件
        $f = fopen($filename, 'w');
        // 写入内容
        fwrite($f, $out);
        // 关闭
        fclose($f);
    }

    /**
     * 获取表字段列表
     * @param string $tableName 数据表名
     * @return array
     */
    public function getColumnList(string $tableName)
    {
        // 获取表列字段信息
        $queryBuild = new QueryBuilder();
        $queryBuild->raw("SELECT COLUMN_NAME,COLUMN_DEFAULT,DATA_TYPE,COLUMN_TYPE,COLUMN_COMMENT FROM information_schema.`COLUMNS` where TABLE_NAME like '{$tableName}'");
        $columnList =  DbManager::getInstance()->query($queryBuild, true);
        $columnList = $columnList->getResult();
        $fields = [];
        if ($columnList) {
            foreach ($columnList as $val) {
                $column = [];
                // 列名称
                $column['columnName'] = $val['COLUMN_NAME'];
                // 列默认值
                $column['columnDefault'] = $val['COLUMN_DEFAULT'];
                // 数据类型
                $column['dataType'] = $val['DATA_TYPE'];
                // 列描述
                if (strpos($val['COLUMN_COMMENT'], '：') !== false) {
                    $item = explode("：", $val['COLUMN_COMMENT']);
                    $column['columnComment'] = $item[0];

                    // 拆解字段描述
                    $param = explode(" ", $item[1]);
                    $columnValue = [];
                    $columnValueList = [];
                    foreach ($param as $vo) {
                        // 键值
                        $key = preg_replace('/[^0-9]/', '', $vo);
                        // 键值内容
                        $value = str_replace($key, null, $vo);
                        $columnValue[] = [
                            'value' => $key,
                            'name' => $value,
                        ];//"{$key}={$value}";
                        $columnValueList[] = $value;
                    }
                    $column['columnValue'] = $columnValue;//implode(',', $columnValue);
                    if ($val['COLUMN_NAME'] == "status" || substr($val['COLUMN_NAME'], 0, 3) == "is_") {
                        $column['columnSwitch'] = true;
                        $column['columnSwitchValue'] = implode('|', $columnValueList);
                        if ($val['COLUMN_NAME'] == "status") {
                            $column['columnSwitchName'] = "status";
                        } else {
                            $column['columnSwitchName'] = 'set' . str_replace(' ', null, ucwords(strtolower(str_replace('_', ' ', $val['COLUMN_NAME']))));
                        }
                    } else {
                        $column['columnSwitch'] = false;
                    }
                } else {
                    $column['columnComment'] = $val['COLUMN_COMMENT'];
                }
                $fields[] = $column;
            }
        }
        return $fields;
    }

    /**
     * 生成模块菜单
     * @param string $moduleName 模块名称
     * @param string $moduleTitle 模块标题
     */
    public function generateMenu(string $moduleName, string $moduleTitle)
    {
        // 查询已存在的菜单
        $menuModel = new MenuModel();
        $info = $menuModel->getOne([
            ['permission' => ["sys:{$moduleName}:view"]],
        ]);
//        print_r($info);
        echo '---------------------------'.PHP_EOL;
        $data = [
            'id' => isset($info['id']) ? intval($info['id']) : 0,
            'title' => $moduleTitle,
            'icon' => 'el-icon-house',
            'path' => "/system/{$moduleName}",
            'component' => "/system/{$moduleName}",
            'pid' => 43,
            'type' => 0,
            'permission' => "sys:{$moduleName}:view",
        ];
        $result = $menuModel->edit($data); // 没有该模块菜单则插入
        if ($result) {
            // 去除表描述中的`管理`
            if (strpos($moduleTitle, "管理") !== false) {
                $moduleTitle = str_replace("管理", null, $moduleTitle);
            }
            // 创建节点
            $funcList = [1, 5, 10, 15, 25, 30];
            foreach ($funcList as $val) {
                $item = [];
                if ($val == 1) {
                    // 查询列表
                    $menuModel = new MenuModel();
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title'=> ["查询" . $moduleTitle]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "查询" . $moduleTitle,
                        'permission' => "sys:{$moduleName}:index",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                } elseif ($val == 5) {
                    // 添加
                    $menuModel = new MenuModel();
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title' => ["添加" . $moduleTitle]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "添加" . $moduleTitle,
                        'permission' => "sys:{$moduleName}:add",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                } elseif ($val == 10) {
                    // 修改
                    $menuModel = new MenuModel();
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title' => ["修改" . $moduleTitle]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "修改" . $moduleTitle,
                        'permission' => "sys:{$moduleName}:edit",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                } elseif ($val == 15) {
                    // 删除
                    $menuModel = new MenuModel();
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title' => ["删除" . $moduleTitle]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "删除" . $moduleTitle,
                        'permission' => "sys:{$moduleName}:delete",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                } elseif ($val == 25) {
                    // 状态
                    $menuModel = new MenuModel();
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title' => ["设置状态"]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "设置状态",
                        'permission' => "sys:{$moduleName}:status",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                } elseif ($val == 30) {
                    // 批量删除
                    $info = $menuModel->getOne([
                        ['pid' => [$result]],
                        ['title' => ["批量删除"]]
                    ]);
                    $item = [
                        'id' => isset($info['id']) ? intval($info['id']) : 0,
                        'title' => "批量删除",
                        'permission' => "sys:{$moduleName}:batchDelete",
                        'pid' => $result,
                        'type' => 1,
                        'status' => 1,
                        'sort' => $val,
                    ];
                }
                $menuModel = new MenuModel();
                $menuModel->edit($item);
            }
        }
    }
}
